#include "StdAfx.h"
#include "Timer.h"
#include <process.h>

CTimer::CTimer(void)
{
	m_init = false;
}

CTimer::~CTimer(void)
{
}

bool CTimer::Init( lua_State* L, const char* name )
{
	if (m_init) return false;

	if (!__super::Init(L, name)) return false;

	lua_getglobal(L, name);

	REG_STATIC_FUNC(L, CTimer, addTimer);
	REG_STATIC_FUNC(L, CTimer, delTimer);

	lua_pop(L, 1);


//	HANDLE handle = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, this, 0, NULL);
//	CloseHandle(handle);
	m_init = true;

	return true;
}

CTimer& CTimer::Instance()
{
	static CTimer timer;
	return timer;
}

int CTimer::addTimer( lua_State* L )
{
	unsigned int index = lua_tointeger(L, -1);
	unsigned int cycle = lua_tointeger(L, -2);
	unsigned int expires = lua_tointeger(L, -3);
	stTime timeInfo;
	timeInfo.index = index;
	timeInfo.lasttime = GetTickCount();
	timeInfo.cycle = cycle;
	timeInfo.expires = expires;

	CTimer& timer = CTimer::Instance();
	timer.m_timerlist.insert(std::make_pair(index, timeInfo));

	return 0;
}

int CTimer::delTimer( lua_State* L )
{
	int index = lua_tointeger(L, -1);
	if (index > 0)
	{
		CTimer& timer = CTimer::Instance();
		TimerList::iterator iter = timer.m_timerlist.find(index);
		if (iter != timer.m_timerlist.end())
		{
			timer.m_timerlist.erase(iter);
			lua_pushboolean(L, true);
			return 1;
		}
	}
	lua_pushboolean(L, false);
	return 1;
}

unsigned int WINAPI CTimer::ThreadFunc( void* pArguments )
{
	CTimer* timer = (CTimer*) pArguments;
	if (timer != NULL)
	{
		return timer->OnTimer();
	}
	
	return 1;
}

int CTimer::OnTimer()
{
// 	while(m_L != NULL)
// 	{
// 		if (m_timerlist.empty())
// 		{
// 			Sleep(10);
// 			continue;
// 		}
		unsigned int curTime = GetTickCount();
		unsigned int timeDiff = 0;
		TimerList::iterator iter = m_timerlist.begin();
		for (; iter != m_timerlist.end();)
		{
			stTime& timer = iter->second;
			timeDiff = TimeDiff(curTime, timer.lasttime);
			if (timer.expires == 0 && timeDiff >= timer.cycle)
			{
				callTimer(iter, timer.index, TimeDiff(GetTickCount(), curTime));
				timer.lasttime = curTime;
			}
			else if (timer.expires > 0 && timeDiff >= timer.expires)
			{
				callTimer(iter, timer.index, TimeDiff(GetTickCount(), curTime));
				timer.expires = 0;
				timer.lasttime = curTime;
			}
			else
				iter++;
		}
	//}
	return 0;
}

bool CTimer::callTimer(TimerList::iterator& iter, unsigned int index, unsigned int diff)
{
	lua_getglobal(m_L, "doTimer");
	lua_pushinteger(m_L, index);
	int argnum = 1;
	if (diff > 100)
	{
		lua_pushinteger(m_L, diff);
		argnum = 2;
	}
	
	int ret = lua_pcall(m_L, argnum, 1, 0);
	if (ret != 0)
	{
		CScript::printLuaError(m_L, ret);
		lua_pop(m_L, 1); 
		return false;
	}
	else
	{
		int ret1 = lua_tointeger(m_L, -1);
		if (ret1 != 1)
		{
			m_timerlist.erase(iter++);
			return true;
		}
		else
		{
			iter++;
		}
	}
	return true;
}

bool CTimer::UnRegisterObject()
{
	return true;
}


